<?php

namespace pmvc\mvc\view\smarty;

use pmvc\template\smarty\SmartyUtil;
use pmvc\template\smarty\SmartyTemplateEngine;

use pmvc\ioc\ObjectFactory;
use pmvc\ioc\InitializingObject;

use pmvc\mvc\ViewHandler;
use pmvc\mvc\Request;
use pmvc\mvc\Response;
use pmvc\mvc\view\PropertiesLookup;
use pmvc\mvc\security\SecurityUtil;

use pmvc\util\ClassUtil;
use pmvc\util\ReflectionUtil;

use pmvc\log\Log;

use Exception;

class SmartyViewHandler 
    implements ViewHandler,
    InitializingObject {

    public $templateEngine;
    public $compileDir;
    public $configDir;
    public $cacheDir;
    public $useCache;
    public $templateDir;
    public $initFunctionName;
    

    /**
     * {@inheritDoc}
     */
	public function initialize() {
		// create a template engine
		if (!isset($this->templateEngine)) {
			$this->templateEngine = new SmartyTemplateEngine();
			$this->templateEngine->compileDir	= $this->compileDir;
			$this->templateEngine->configDir	= $this->configDir;
			$this->templateEngine->cacheDir		= $this->cacheDir;
			$this->templateEngine->useCache		= $this->useCache;
			$this->templateEngine->templateDir	= $this->templateDir;
			$this->templateEngine->initialize();

		// check injected SmartyTemplateEngine
		} else if (!ReflectionUtil::isInstance($this->templateEngine,
			'pmvc\template\smarty\SmartyTemplateEngine')) {
			throw new Exception("SmartyViewHandler can only use SmartyTemplateEngine");
		}
	}
    
    /**
     * {@inheritDoc}
     */
	public function renderView(Request $request, Response $response, $viewName) {

		// create the template
		$template = $this->templateEngine->getTemplate($viewName);

		// get smarty
		$smarty = $template->getSmarty();
        
        // set variables
        SmartyUtil::assignTemplateVars($smarty, Array(
            "request"		=> $request->getParameters(),
            "session"       => $request->getSessionVariables(),
            "server"	    => $request->getServerVariables(),
        	"requestedUrl"	=> $request->getRequestedUrl(),
        	"contextUrl"	=> $request->getContextUrl(),
        	"baseUrl"		=> $request->getBaseUrl(),
        	"security"		=> Array(
        		"user" => SecurityUtil::getCurrentUser($request),
        		"isLoggedIn" => SecurityUtil::isLoggedIn($request)
        	)
        ));
        SmartyUtil::registerObject($smarty, "Request", $request, Array());
        SmartyUtil::registerObject($smarty, "Response", $response, Array());

        $contextProperties = $request->getDispatcher()->getApplicationContext()->getObjectsOfType('pmvc\Properties');
        if (!empty($contextProperties)) {
        	$propertiesLookup = new PropertiesLookup();
        	$propertiesLookup->addAll($contextProperties);
        	SmartyUtil::registerObject($smarty,
        		'ContextPropertiesLookup', $propertiesLookup, Array());
        }
        
        // register plugins
        $plugins = __DIR__."/plugins";
        $pluginsRp = realpath(__DIR__."/plugins");
        SmartyUtil::addPluginDir($smarty, $pluginsRp!==false ? $pluginsRp : $plugins);

		// init function
		if (isset($this->initFunctionName)
			&& function_exists($this->initFunctionName)) {
			$func = $this->initFunctionName;
			$func($smarty, $request, $response);

		} else if (isset($this->initFunctionName)) {
			throw new Exception("Init function ".$this->initFunctionName." not found");
		}
		
        // put the model into the template
        SmartyUtil::assignTemplateVars($smarty, $response->getModel()->getArrayCopy());
        
        // render the view
        $template->render($response->getModel()->getArrayCopy(), $response->getStream());
    }
}

?>